//
//  PMDemo.m
//  PezMonkeyTest
//
//  Created by Spence DiNicolantonio on 11/3/09.
//  Copyright 2009 Necrosoft. All rights reserved.
//

#import "PMDemo.h"


@implementation PMDemo

@synthesize space;


#pragma mark -
#pragma mark Init

- (id)init {
	if (![super init])
		return nil;
	
	// initialize the demo
	[self initDemo];
	
	return self;
}


#pragma mark -
#pragma mark Dealloc

- (void)dealloc {
	[self.space release];
	[super dealloc];
}


#pragma mark -
#pragma mark Other Methods

- (void)draw {
	// clear screen
	glClear(GL_COLOR_BUFFER_BIT);
	
	// draw objects black
	glColor3f(0.0, 0.0, 0.0);
	for (PMShape *shape in [space allShapes])
		[PMDemo drawShape:shape];
	
#pragma mark Fix
	// draw mouse-over red
	glColor3f(1.0, 0.0, 0.0);
	//cpSpaceShapePointQuery(space.cpSpace, mousePoint, pickingFunc, NULL);
	//cpSpaceStaticShapePointQuery(space.cpSpace, mousePoint, pickingFunc, NULL);
	
	glBegin(GL_POINTS); 
	{
		// draw body center points blue
		glColor3f(0.0, 0.0, 1.0);
		for(PMBody *body in [space bodies])
			glVertex2f(body.position.x, body.position.y);
		
#pragma mark Fix
		// draw collisions red
		glColor3f(1.0, 0.0, 0.0);
		//cpArrayEach(space.cpSpace->arbiters, &drawCollisions, NULL);
	} 
	glEnd();
}


#pragma mark -
#pragma mark Drawing

+ (void)drawShape:(PMShape *)shape {
	switch([shape type]){
		case PMShapeTypeCircle:
			[self drawCircleShape:(PMCircleShape *)shape];
			break;
		case PMShapeTypeSegment:
			[self drawSegmentShape:(PMSegmentShape *)shape];
			break;
		case PMShapeTypePolygon:
			[self drawPolygonShape:(PMPolygonShape *)shape];
			break;
		default:
			NSLog(@"Error in drawShape: Invalid PMShape Type");
	}
}

+ (void)drawCircleShape:(PMCircleShape *)circle {
	PMBody *body = [circle body];
	PMVect rotatedCenterOffset = PMVectRotate([circle center], [body rotationVector]);
	PMVect position = PMVectAdd([body position], rotatedCenterOffset);
	[PMDemo drawCircleAtPoint:position 
					   radius:[circle radius] 
						angle:[body angle]];
}

+ (void)drawSegmentShape:(PMSegmentShape *)segment {
	PMBody *body = [segment body];
	PMVect rotatedStart = PMVectRotate([segment start], [body rotationVector]);
	PMVect rotatedEnd = PMVectRotate([segment end], [body rotationVector]);
	PMVect worldStart = PMVectAdd([body position], rotatedStart);
	PMVect worldEnd = PMVectAdd([body position], rotatedEnd);
	
	glBegin(GL_LINES);
	{
		glVertex2f(worldStart.x, worldStart.y);
		glVertex2f(worldEnd.x, worldEnd.y);
	}
	glEnd();
}

+ (void)drawPolygonShape:(PMPolygonShape *)polygon {
	PMBody *body = [polygon body];
	NSUInteger vertCount = [polygon vertexCount];
	PMVect *verts = [polygon vertices];
	
	glBegin(GL_LINE_LOOP);
	{
		for(int i=0; i<vertCount; i++) {
			PMVect rotatedVertex = PMVectRotate(verts[i], [body rotationVector]);
			PMVect worldVertex = PMVectAdd([body position], rotatedVertex);
			glVertex2f(worldVertex.x, worldVertex.y);
		}
	}
	glEnd();
}

+ (void)drawCircleAtPoint:(PMVect)point radius:(float)radius angle:(float)angle {
	const int segs = 15;
	const float coef = 2.0*M_PI/(float)segs;
	
	glBegin(GL_LINE_STRIP); 
	{
		for(int n=0; n<=segs; n++) {
			float rads = n*coef;
			glVertex2f(radius*cos(rads + angle) + point.x, 
					   radius*sin(rads + angle) + point.y);
		}
		glVertex2f(point.x, point.y);
	} 
	glEnd();
}


#pragma mark -
#pragma mark Abstract Methods

- (void)initDemo {}
- (void)update {}

@end
